package ta;

import common.SimpleXMLGenerator;
import org.xml.sax.DTDHandler;
import org.xml.sax.SAXException;
import ta.structure.TADefinition;

public class TAGenerator extends SimpleXMLGenerator
{
    public TADefinition ta;

    public TAGenerator(TADefinition ta, String file_path, String file_name_no_ext)
    {
        super(file_path, file_name_no_ext);
        this.ta = ta;
    }

    @Override
    public void generate() throws SAXException
    {
        handler.startDocument();

        openElement("nta");
        // global declarations
        openElement("declaration");
        setContent(ta.getGlobals().generateDeclarations());
        closeElement("declaration");
        // templates
        for (var t : ta.getTemplates().values())
        {
            if (t.isUnused())
                continue;
            openElement("template");
            // template name
            openElement("name");
            setContent(t.getName());
            closeElement("name");
            // template parameters
            openElement("parameter");
            setContent(t.getParameters());
            closeElement("parameter");
            // local declarations
            openElement("declaration");
            setContent(t.getLocals().generateDeclarations());
            closeElement("declaration");
            // locations
            for (var n : t.getLocations())
            {
                var attr = getAttrImplInstance();
                attr.addAttribute("", "", "id", "", n.getId());
                attr.addAttribute("", "", "x", "", String.valueOf(n.x));
                attr.addAttribute("", "", "y", "", String.valueOf(n.y));
                openElement("location", attr);

                var nameAttr = getAttrImplInstance();
                nameAttr.addAttribute("", "", "x", "", String.valueOf(n.x - 10));
                nameAttr.addAttribute("", "", "y", "", String.valueOf(n.y + TALayoutHelper.LABEL_NAME_Y));
                openElement("name", nameAttr);

                setContent(n.getName());
                closeElement("name");

                closeElement("location");
            }
            // init
            var initAttr = getAttrImplInstance();
            initAttr.addAttribute("", "", "ref", "", t.getInitRef());
            openElement("init", initAttr);
            closeElement("init");
            // transitions
            for (var trans : t.getTransitions())
            {
                openElement("transition");
                // sourceRef
                var sourceAttr = getAttrImplInstance();
                sourceAttr.addAttribute("", "", "ref", "", trans.getSourceRef());
                openElement("source", sourceAttr);
                closeElement("source");
                // targetRef
                var targetAttr = getAttrImplInstance();
                sourceAttr.addAttribute("", "", "ref", "", trans.getTargetRef());
                openElement("target", targetAttr);
                closeElement("target");
                // labels
                // select
                if (trans.getSelect() != null)
                {
                    var selectAttr = getAttrImplInstance();
                    selectAttr.addAttribute("", "", "kind", "", "select");
                    selectAttr.addAttribute("", "", "x", "", String.valueOf(trans.x));
                    selectAttr.addAttribute("", "", "y", "", String.valueOf(trans.y + TALayoutHelper.LABEL_SELECT_Y));
                    openElement("label", selectAttr);
                    setContent(trans.getSelect());
                    closeElement("label");
                }
                // guard
                if (trans.getGuard() != null)
                {
                    var guardAttr = getAttrImplInstance();
                    guardAttr.addAttribute("", "", "kind", "", "guard");
                    guardAttr.addAttribute("", "", "x", "", String.valueOf(trans.x));
                    guardAttr.addAttribute("", "", "y", "", String.valueOf(trans.y + TALayoutHelper.LABEL_GUARD_Y));
                    openElement("label", guardAttr);
                    setContent(trans.getGuard());
                    closeElement("label");
                }
                // select
                if (trans.getSync() != null)
                {
                    var syncAttr = getAttrImplInstance();
                    syncAttr.addAttribute("", "", "kind", "", "synchronisation");
                    syncAttr.addAttribute("", "", "x", "", String.valueOf(trans.x));
                    syncAttr.addAttribute("", "", "y", "", String.valueOf(trans.y + TALayoutHelper.LABEL_SYNC_Y));
                    openElement("label", syncAttr);
                    setContent(trans.getSync());
                    closeElement("label");
                }
                // select
                if (trans.getUpdate() != null)
                {
                    var updateAttr = getAttrImplInstance();
                    updateAttr.addAttribute("", "", "kind", "", "assignment");
                    updateAttr.addAttribute("", "", "x", "", String.valueOf(trans.x));
                    updateAttr.addAttribute("", "", "y", "", String.valueOf(trans.y + TALayoutHelper.LABEL_UPDATE_Y));
                    openElement("label", updateAttr);
                    setContent(trans.getUpdate());
                    closeElement("label");
                }
                closeElement("transition");
            }
            closeElement("template");
        }
        // system
        openElement("system");
        setContent(ta.generateSystem());
        closeElement("system");

        closeElement("nta");

        handler.endDocument();
    }
}
